package com.dvg.scores;

import java.util.Vector;

import net.rim.device.api.system.Application;
import net.rim.device.api.system.CoverageInfo;
import net.rim.device.api.system.RadioInfo;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BasicEditField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.container.DialogFieldManager;
import net.rim.device.api.ui.container.PopupScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;

import org.json.me.JSONArray;
import org.json.me.JSONException;
import org.json.me.JSONObject;

import com.dvg.data.Storage;
import com.dvg.http.HttpCore;
import com.dvg.http.IHttpCallback;
import com.dvg.http.UrlParameter;

public class ScoresModule implements IHttpCallback{
	private final String KEY_GAME_NAME = "game_name";
	private final String KEY_COMMAND = "command";
	private final String KEY_NEW_USER = "new_user";
	private final String KEY_VALUE = "scores_value";
	private final String KEY_STARS = "stars";
	private final String KEY_LEVELS = "levels";
	private final String KEY_USER_NAME = "user_name";
	
	private PopupScreen enterUserNmamePopup = null;
	
	private static ScoresModule instance = null;
	
	private HttpCore httpEngine = null;
	
	private String connectionParameter; 
	
	private Vector urlParameters;
	
	private IHttpResponseListener _listener;
	
	private BasicEditField edit;
	
	private String __gameName = "";
	private int __value;
	private int __stars;
	private int __levels;
	
	private ScoresModule(){
		Storage st = new Storage();
	}
	
	public static ScoresModule getInstance(){
		if (instance == null){
			instance = new ScoresModule();
		}
		
		return instance;
	}

	public void notifySuxcess(byte[] data) {
		String responseString = new String(data);
		if (responseString.indexOf("[{") == -1 && responseString.indexOf("ok") == -1 && responseString.indexOf("user exists!") == -1){
			UiApplication.getUiApplication().invokeAndWait(new Runnable() {
				
				public void run() {
					Storage.setUserName("");
					Dialog.inform("Something wrong.\nProbably your device not connected to internet.");
				}
			});	
			this.httpEngine = null;
			System.gc();
			return;
		} else if (responseString.indexOf("[{") == -1 && responseString.indexOf("ok") != -1 && responseString.indexOf("user exists!") == -1){
			UiApplication.getUiApplication().invokeAndWait(new Runnable() {
				
				public void run() {
					Dialog.inform("Your scores posted!");
				}
			});
			this.httpEngine = null;
			System.gc();
			return;
		} else if (responseString.indexOf("[{") == -1 && responseString.indexOf("ok") == -1 && responseString.indexOf("user exists!") != -1){
			UiApplication.getUiApplication().invokeAndWait(new Runnable() {
				
				public void run() {
					synchronized (Application.getEventLock()) {
						Dialog.inform("Such user name allready exists!\nTry to select another name or modify current.");
					}
					Storage.setUserName("");
					postScores(__gameName, __value, __stars, __levels);
				}
			});
		}
		Record[] records = null;
		try {
			JSONArray _records = new JSONArray(responseString);
			records = new Record[_records.length()];
			for(int i = 0; i < _records.length(); i++){
				JSONObject obj = _records.getJSONObject(i);
				records[i] = new Record(obj.getString("userName"), obj.getInt("scores"), obj.getInt("levels"), obj.getInt("stars"));
			}
		} catch (JSONException e) {
		}
		this._listener.processResponse(records);
		this.httpEngine = null;
		System.gc();
	}

	public void notfyError(int errorCode, String message) {
		
	}
	
	private String getConnectionParameter(){
		String suffix = "";
		
		if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_MDS)) 
        {
              // BES is available
              suffix = ";deviceside=false";
        }
        else if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_BIS_B)) 
        {
              // BIS is available
              suffix = ";deviceside=false;ConnectionType=mds-public";
        }
        else if (RadioInfo.areWAFsSupported(RadioInfo.WAF_WLAN) && 
        		CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_DIRECT, RadioInfo.WAF_WLAN, false)) 
        {
              // wifi is available
              suffix = ";deviceside=true;interface=wifi";
        }
        else if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_DIRECT)) {
              // attempt to use direct tcp connection
              suffix = ";deviceside=true";
        }
		
		return suffix;
	}
	
	public void getSores(String gameName){
		this.httpEngine = new HttpCore(this);
		this.httpEngine.set_targetScript(ScoreModuleParameters.TARGET_SCRIPT);
		this.httpEngine.set_requestMethod(HttpCore.REQUEST_METHOD_GET);
		this.httpEngine.set_connectionParameter(getConnectionParameter());
		this.urlParameters = new Vector();
		this.urlParameters.addElement(new UrlParameter(KEY_GAME_NAME, gameName));
		this.urlParameters.addElement(new UrlParameter(KEY_COMMAND, "get_scores"));
		this.httpEngine.set_urlParameters(this.urlParameters);
		this.httpEngine.processRequest();
	}
	
	public void postScores(String gameName, int value, int stars, int levels){
		if (!Storage.getUserName().equals("")){
			_postScores(gameName, value, stars, levels, false);
		} else {
			__gameName = gameName;
			__value = value;
			__stars = stars;
			__levels = levels;
			showDialog(gameName, value, stars, levels);
		}
	}
	
	private void _postScores(String gameName, int value, int stars, int levels, final boolean isNewUser){
		this.httpEngine = new HttpCore(this);
		this.httpEngine.set_targetScript(ScoreModuleParameters.TARGET_SCRIPT);
		this.httpEngine.set_requestMethod(HttpCore.REQUEST_METHOD_GET);
		this.httpEngine.set_connectionParameter(getConnectionParameter());
		this.urlParameters = new Vector();
		this.urlParameters.addElement(new UrlParameter(KEY_GAME_NAME, gameName));
		this.urlParameters.addElement(new UrlParameter(KEY_COMMAND, "post_scores"));
		this.urlParameters.addElement(new UrlParameter(KEY_USER_NAME, Storage.getUserName()));
		this.urlParameters.addElement(new UrlParameter(KEY_VALUE, String.valueOf(value)));
		this.urlParameters.addElement(new UrlParameter(KEY_STARS, String.valueOf(stars)));
		this.urlParameters.addElement(new UrlParameter(KEY_LEVELS, String.valueOf(levels)));
		this.urlParameters.addElement(new UrlParameter(KEY_NEW_USER, String.valueOf(isNewUser)));
		this.httpEngine.set_urlParameters(this.urlParameters);
		this.httpEngine.processRequest();
	}
	
	public void setResponseListener(IHttpResponseListener listener) {
		this._listener = listener;
	}
	
	private void showDialog(final String gameName, final int value, final int stars, final int levels){
		DialogFieldManager dfm = new DialogFieldManager();
		VerticalFieldManager vfm = new VerticalFieldManager();
		edit = new BasicEditField("Name: ", "");
		ButtonField btn = new ButtonField("Ok", ButtonField.CONSUME_CLICK);
		btn.setChangeListener(new FieldChangeListener() {
			
			public void fieldChanged(Field field, int context) {
				Storage.setUserName(edit.getText());
				UiApplication.getUiApplication().popScreen(enterUserNmamePopup);
				enterUserNmamePopup = null;
				_postScores(gameName, value, stars, levels, true);
			}
		});
		vfm.add(edit);
		vfm.add(btn);
		dfm.addCustomField(vfm);
		this.enterUserNmamePopup = new PopupScreen(dfm, PopupScreen.DEFAULT_CLOSE);
		UiApplication.getUiApplication().pushScreen(enterUserNmamePopup);
	}
}
